package com.tomdd.exception;

import com.tomdd.model.resp.Result;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.ValidationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Objects;

/**
 * 全局异常拦截
 *
 * @author zx
 * @date 2024-07-18 20:27
 */
@RestControllerAdvice
@Slf4j
public class GlobaException {


    @ExceptionHandler(Exception.class)
    public Result<?> handleException(Exception e){
        StackTraceElement[] stackTrace = e.getStackTrace();
        StackTraceElement traceElement = stackTrace[0];
        String className = traceElement.getClassName();
        String methodName = traceElement.getMethodName();
        int lineNumber = traceElement.getLineNumber();
        String fileName = traceElement.getFileName();
        String message = e.getMessage();
        String errorMess = String.format("className:%s,methodName:%s,lineNumber:%s,fileName:%s,message:%s",
                className, methodName, lineNumber, fileName, message);
        log.info("错误详细信息:{}", errorMess);
        e.printStackTrace();
        return Result.error(StringUtils.hasLength(e.getMessage())? e.getMessage() : "操作失败");
    }
    
    
    /**
     * ValidationException
     *
     * @param v ValidationException 对象
     * @return 异常信息 基本信息
     */
    @ExceptionHandler(ValidationException.class)
    public Result<?> handlevalidationException(ValidationException v) {
        log.error("ValidationException:{}", v.getCause().getMessage());
        return Result.error(v.getCause().getMessage());
    }


    /**
     * ConstraintViolationException 构造方法校验
     *
     * @param c ValidationException 对象
     * @return 异常信息 基本信息
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public Result<?> handleConstraintViolationException(ConstraintViolationException c) {
        log.error("ConstraintViolationException:{}", c.getMessage());
        return Result.error(c.getMessage());
    }


    /**
     * 方法校验错误
     *
     * @param m 方法校验异常对象
     * @return 异常信息 基本信息
     */

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException m) {
        log.error("MethodArgumentNotValidException:{}",
                Objects.requireNonNull(m.getBindingResult().getFieldError()).getDefaultMessage());
        return Result.error(m.getBindingResult().getFieldError().getDefaultMessage());
    }

    /**
     * 参数绑定异常
     *
     * @param bindException validationg 参数绑定异常
     * @return 参数绑定异常信息
     */
    @ExceptionHandler(BindException.class)
    public Result<?> banPropertyBindingException(BindException bindException) {
        return Result.error(Objects.requireNonNull(bindException.getBindingResult().getFieldError()).getDefaultMessage());
    }
}
